package info

import (
	"encoding/json"
	"fmt"
	"reflect"
	"strconv"
	"time"

	"github.com/yusufpapurcu/wmi"
	"gopkg.in/ini.v1"
)

type Win32_DiskDrive struct {
	Availability                uint16    `json:"可用性"`
	BytesPerSector              uint32    `json:"每扇区字节数"`
	Capabilities                []int     `json:"功能"` //[]uint16出错
	CapabilityDescriptions      []string  `json:"功能描述"`
	Caption                     string    `json:"说明"`
	CompressionMethod           string    `json:"算法或工具"`
	ConfigManagerErrorCode      uint32    `json:"错误代码"`
	ConfigManagerUserConfig     bool      `json:"用户定义的配置"`
	CreationClassName           string    `json:"创建类名称"`
	DefaultBlockSize            uint64    `json:"默认块大小"`
	Description                 string    `json:"描述"`
	DeviceID                    string    `json:"设备标识"`
	ErrorCleared                bool      `json:"错误"`
	ErrorDescription            string    `json:"错误详细信息"`
	ErrorMethodology            string    `json:"错误检测和纠正类型"`
	FirmwareRevision            string    `json:"固件修订"`
	Index                       uint32    `json:"驱动器号"`
	InstallDate                 time.Time `json:"安装时间"`
	InterfaceType               string    `json:"接口类型"`
	LastErrorCode               uint32    `json:"最后错误代码"`
	Manufacturer                string    `json:"制造商"`
	MaxBlockSize                uint64    `json:"最大块大小"`
	MaxMediaSize                uint64    `json:"媒体最大大小"`
	MediaLoaded                 bool      `json:"介质是否加载"`
	MediaType                   string    `json:"媒体类型"`
	MinBlockSize                uint64    `json:"最小块大小"`
	Model                       string    `json:"驱动器型号"`
	Name                        string    `json:"名字"`
	NeedsCleaning               bool      `json:"需要清理"`
	NumberOfMediaSupported      uint32    `json:"最大媒体数"`
	Partitions                  uint32    `json:"分区"`
	PNPDeviceID                 string    `json:"即插即用设备标识"`
	PowerManagementCapabilities []uint16  `json:"特定功能"`
	PowerManagementSupported    bool      `json:"电源功能"`
	SCSIBus                     uint32    `json:"SCSI总线编号"`
	SCSILogicalUnit             uint16    `json:"SCSI逻辑单元号 "`
	SCSIPort                    uint16    `json:"SCSI端口号"`
	SCSITargetId                uint16    `json:"SCSI标识符号"`
	SectorsPerTrack             uint32    `json:"磁道中扇区数"`
	SerialNumber                string    `json:"序列号"`
	Signature                   uint32    `json:"磁盘标识"`
	Size                        uint64    `json:"大小"`
	Status                      string    `json:"状态"`
	StatusInfo                  uint16    `json:"逻辑设备的态"`
	SystemCreationClassName     string
	SystemName                  string `json:"系统名称"`
	TotalCylinders              uint64 `json:"支持大容量磁盘大小"`
	TotalHeads                  uint32 `json:"磁头总数"`
	TotalSectors                uint64 `json:"扇区总数"`
	TotalTracks                 uint64 `json:"磁道总数"`
	TracksPerCylinder           uint32 `json:"磁道数"`
}

func DiskInfo() (info []Win32_DiskDrive, err error) {
	err1 := wmi.Query("Select * from Win32_DiskDrive", &info)
	if err1 != nil {
		return nil, err1
	}
	return info, nil
}

func MapJsonDiskInfo() (data []map[string]interface{}, err error) {

	info, err := DiskInfo()
	if err != nil {
		return data, err
	}

	t, err := json.Marshal(info)
	if err != nil {
		return data, err
	}
	json.Unmarshal(t, &data)
	cfg, err1 := ini.Load("./info/diskconfig.ini")
	if err1 != nil {
		return data, err
	}
	/*for _, v := range data {
		for k, v1 := range v {
			if k == "功能" {
				valstring := []string{}
				for _, v2 := range v1.([]interface{}) {
					vs := v2.(float64)
					valstring = append(valstring, cfg.Section(cfg.Section("").Key("功能").String()).Key(strconv.Itoa(int(vs))).String())
				}
				v[k] = valstring

			}
		}
	}
	return data, nil
	*/
	list := []string{"功能", "可用性", "错误代码"}
	for _, v := range data {
		for _, vl := range list {
			switch v[vl].(type) {
			case float64:
				v[vl] = cfg.Section(cfg.Section("").Key(vl).String()).Key(strconv.Itoa(int(v[vl].(float64)))).String()
			case []interface{}:
				valstring := []string{}
				for _, v2 := range v[vl].([]interface{}) {
					vs := v2.(float64)
					valstring = append(valstring, cfg.Section(cfg.Section("").Key(vl).String()).Key(strconv.Itoa(int(vs))).String())
				}
				v[vl] = valstring

			}
			if a, ok := v[vl].(float64); ok {
				v[vl] = cfg.Section(cfg.Section("").Key(vl).String()).Key(strconv.Itoa(int(a))).String()
			} else {
				continue
			}

		}
		//fmt.Println(cfg.Section(d.String()).Key(fmt.Sprintf("%v", v1)))
	}
	for _, vd := range data {

		if v, ok := vd["大小"].(float64); ok {
			if v > 1000000000 {
				vd["大小"] = fmt.Sprintf("%d", (int64(v)/1000000000)) + "GB"
			} else {
				vd["大小"] = strconv.Itoa(int(v)) + "B"
			}

		}
		if v, ok := vd["磁盘标识"].(float64); ok {

			vd["磁盘标识"] = strconv.FormatFloat(v, 'f', 0, 64)
		}
		if v, ok := vd["磁道总数"].(float64); ok {

			vd["磁道总数"] = strconv.FormatFloat(v, 'f', 0, 64)

		}
		if v, ok := vd["扇区总数"].(float64); ok {

			vd["扇区总数"] = strconv.FormatFloat(v, 'f', 0, 64)

		}

	}
	return data, nil
}

func JsonDiskInfoEn() (f interface{}, err error) {
	disk, err := DiskInfo()
	if err != nil {
		return "", err
	}

	jsonData := make(map[string]interface{})
	jsonDataList := make([]map[string]interface{}, 0)
	//cpu1 := cpu[0]
	for _, cpu1 := range disk {
		diskType := reflect.TypeOf(cpu1)
		cpuValue := reflect.ValueOf(&cpu1)
		for i := 0; i < diskType.NumField(); i++ {
			field := diskType.Field(i)                                  // 获取字段信息
			jsonData[field.Name] = cpuValue.Elem().Field(i).Interface() // 将字段值添加到 JSON 数据中
			fieldValue := diskType.Field(i).Tag                         // 获取字段的值
			println(field.Name)
			println("================")
			println(fieldValue)
			//println(field.Name, fieldValue.Get("json"))
			// 将字段值添加到 JSON 数据中，不使用 tag 标签指定 JSON 键的名称
		}
		jsonDataList = append(jsonDataList, jsonData)
	}

	t, jsonErro := json.Marshal(jsonDataList)
	if jsonErro != nil {
		return "", jsonErro
	}
	return t, nil

}
